﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YasharEl.Infrastructure.PresentationModel.ComponentModel;
using System.ComponentModel;
using System.Runtime.Serialization;
using YasharEl.Infrastructure.PresentationModel.Views;

namespace YasharEl.Infrastructure.PresentationModel.ViewModels
{
    /// <summary>
    /// A base implementation of the <see cref="IViewModel"/> interface.
    /// </summary>
    public abstract class ViewModelBase : NotifyPropertyChangeBase, IViewModel, INotifyPropertyChanged
    {
        protected ViewModelBase()
        {
            Initialize();
        }

        [OnDeserializing]
        internal void OnDeserializing(StreamingContext context)
        {
            Initialize();
        }

        /// <summary>
        /// When deserialization occurs fields are not instantiated,
        /// therefore we must instanciate the notifier.
        /// </summary>
        void Initialize()
        {
        }

        #region Id Property

        readonly Guid id = Guid.NewGuid();
        public Guid Id
        {
            get
            {
                return id;
            }
        }

        #endregion

        #region Title Property

        object title;

        [Description("The text to display on a tab.")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public object Title
        {
            get
            {
                return title;
            }
            set
            {
                Assign("Title", ref title, value);
            }
        }

        #endregion

        #region Dimensions

        double width = 300;

        public double Width
        {
            get
            {
                return width;
            }
            set
            {
                Assign("Width", ref width, value);
            }
        }

        double height = 300;

        public double Height
        {
            get
            {
                return height;
            }
            set
            {
                Assign("Height", ref height, value);
            }
        }
        #endregion

        #region Static Methods

        public static T FindType<T>(object view) where T : class
        {
            var result = view as T;
            if (result != null)
            {
                return result;
            }
            var temp = view as IView;
            if (temp != null)
            {
                return temp.ViewModel as T;
            }
            return null;
        }

        #endregion

        #region Object Overrides

        public override string ToString()
        {
            return title != null ? title.ToString() : base.ToString();
        }

        #endregion
    }
}
